package com.amigo.online.common.base.controller;


import com.amigo.online.common.base.exception.BaseException;
import com.amigo.online.common.core.response.Meta;
import com.amigo.online.common.core.response.Response;
import com.amigo.online.common.core.response.StatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 * 基础控制器
 *
 * @author amigo
 */
public abstract class BaseController {

    protected final Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 设置成功响应代码
     */
    protected ResponseEntity<Response> success() {
        return setResponse(StatusCode.OK, true, StatusCode.OK.msg(), null);
    }

    /**
     * 设置成功响应代码
     */
    protected ResponseEntity<Response> success(Object data) {
        return setResponse(StatusCode.OK, true, StatusCode.OK.msg(), data);
    }

    /**
     * 设置失败响应代码
     */
    protected ResponseEntity<Response> failure() {
        return setResponse(StatusCode.BAD_REQUEST, false, StatusCode.BAD_REQUEST.msg(), null);
    }

    /**
     * 设置失败响应代码
     */
    protected ResponseEntity<Response> failure(StatusCode code) {
        return setResponse(code, false, code.msg(), null);
    }

    /**
     * 响应报文
     *
     * @param code    状态码
     * @param success 是否成功
     * @param message 消息
     * @param data    数据
     * @return 响应实体
     */
    protected ResponseEntity<Response> setResponse(StatusCode code, boolean success, String message, Object data) {
        return setResponse(code.value(), success, message, data);
    }

    protected ResponseEntity<Response> setResponse(int code, boolean success, String message, Object data) {
        return ResponseEntity.ok(new Response(code, success, message, data));
    }


    /**
     * 405,方法不被允许
     *
     * @param e
     * @return
     */
    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    @ResponseBody
    public ResponseEntity<Response> exception(HttpRequestMethodNotSupportedException e) {
        logger.error("请求方式异常 => {}", e.getMessage());
        return ResponseEntity.ok(new Response(StatusCode.METHOD_NOT_ALLOWED.value(),
                false, StatusCode.METHOD_NOT_ALLOWED.msg(), null));
    }

    /**
     * 400,请求参数异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<Response> methodArgumentNotValidException(MethodArgumentNotValidException ex) {
        BindingResult result = ex.getBindingResult();
        logger.error("请求参数异常 => {}", StatusCode.BAD_REQUEST.value() + " | " + result.getFieldError().getDefaultMessage(),ex);
        return ResponseEntity.ok(new Response(StatusCode.BAD_REQUEST.value(),
                false, StatusCode.BAD_REQUEST.msg(), null));
    }

    /**
     * 业务异常.
     * @param ex
     * @return
     */
    @ExceptionHandler(BaseException.class)
    @ResponseStatus(HttpStatus.OK)
    @ResponseBody
    public ResponseEntity<Response> businessException(BaseException ex) {
        Meta meta = new Meta();
        ex.handler(meta);
        logger.error("业务异常 => {}", meta.getMsg());
        return ResponseEntity.ok(new Response(meta.getCode(),
                meta.isSuccess(), meta.getMsg(), null));
    }

    /**
     * 500异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public ResponseEntity<Response> exception(Exception ex) {
        ex.printStackTrace();
        return ResponseEntity.ok(new Response(StatusCode.INTERNAL_SERVER_ERROR.value(),
                false, StatusCode.INTERNAL_SERVER_ERROR.msg(), null));
    }


///    @ExceptionHandler(Exception.class)
//    public ResponseEntity<Response> exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception ex) {
//        Meta meta = new Meta();
//        if (ex instanceof BaseException) {
//            ((BaseException) ex).handler(meta);
//            logger.error("发生异常==> {}", meta.getMsg());
//        } else if (ex instanceof IllegalArgumentException) {
//            new IllegalParameterException(ex.getMessage()).handler(meta);
//            logger.error("发生异常==> {}", meta.getMsg());
//        } else if (ex instanceof MethodArgumentNotValidException) {
//
//            logger.error("{}", ((MethodArgumentNotValidException) ex).getBindingResult().getFieldError());
//            meta.setCode(StatusCode.BAD_REQUEST.value());
//            meta.setSuccess(false);
//            meta.setMsg(StatusCode.BAD_REQUEST.msg());
//        } else if (ex instanceof BindException) {
//            logger.error("{}", ((BindException) ex).getFieldError());
//            meta.setCode(StatusCode.BAD_REQUEST.value());
//            meta.setSuccess(false);
//            meta.setMsg(StatusCode.BAD_REQUEST.msg());
//        } else if (ex instanceof ConstraintViolationException) {
//            logger.error("{}", ((ConstraintViolationException) ex).getMessage());
//            meta.setCode(StatusCode.BAD_REQUEST.value());
//            meta.setSuccess(false);
//            meta.setMsg(StatusCode.BAD_REQUEST.msg());
//        } else {
//            meta.setSuccess(false);
//            meta.setCode(StatusCode.INTERNAL_SERVER_ERROR.value());
//            meta.setMsg(StatusCode.INTERNAL_SERVER_ERROR.msg());
//            ex.printStackTrace();
//        }
//
//        return ResponseEntity.ok(new Response(meta.getCode(), meta.isSuccess(), meta.getMsg(), null));
//    }
}
